﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Reflection;
using MySQL.Db;
using Gollie.WebCache;

namespace Gollie.DataTables
{
	public class ActiveOffersToBind
	{
		public uint OfferId { get; set; }
		public int NumberMax { get; set; }
		public int NumberLeft { get; set; }
		public decimal Credit { get; set; }
		public decimal Price { get; set; }
		public uint ExpiresAfter { get; set; }
		public DateTime ValidFrom { get; set; }
		public DateTime ValidTo { get; set; }
		public DateTime EntryDate { get; set; }
		public string Description { get; set; }
		public string Profit { get; set; }
	}

	public class ActiveOffersPerVendor : BaseBindable<ActiveOffersToBind>
	{
		private uint vendorId;
		private static string cacheName = "activeofferspervendor";

		public ActiveOffersPerVendor(uint vendorId)
		{
			this.vendorId = vendorId;

			ResultSet resultSet = Database.Queries.GetActiveOffersPerVendor(vendorId);

			this.AddDetails(resultSet);
		}

		public void AddDetails(ResultSet resultSet)
		{
			int numRows = resultSet.Count;

			for (int i = 0; i < numRows; i++)
			{
				uint offerId = resultSet.GetUInt32(i, "id");
				int numberMax = resultSet.GetInt32(i, "numbermax");
				int numberSold = resultSet.GetInt32(i, "numbersold");
				decimal credit = resultSet.GetDecimal(i, "credit");
				decimal price = resultSet.GetDecimal(i, "price");
				decimal profitEuro = credit - price;
				decimal profitPercentage = profitEuro / price;
				string profitString = string.Format("{0:c} ({1:0%})", profitEuro, profitPercentage);
				uint expiresAfter = resultSet.GetUInt32(i, "expiresafter");

				int left = (numberMax == 0 ? 999999999 : numberMax - numberSold);

				DateTime validFrom = resultSet.GetDateTime(i, "validfrom");

				DateTime validTo = resultSet.GetDateTime(i, "validto");

				DateTime entryDate = resultSet.GetDateTime(i, "entrydate");

				string description = resultSet.GetString(i, "description");

				this.Add(new ActiveOffersToBind()
				{
					OfferId = offerId, NumberMax = numberMax, NumberLeft = left, Credit = credit, Description = description, EntryDate = entryDate, ExpiresAfter = expiresAfter, Price = price, Profit = profitString, ValidFrom = validFrom, ValidTo = validTo
				});
			}
		}

		internal static ActiveOffersPerVendor Instance(uint vendorId)
		{
			string cacheKey = cacheName + vendorId.ToString();
			ActiveOffersPerVendor offers = (ActiveOffersPerVendor)DataCache.Cache[cacheKey];
			if (offers == null)
			{
				offers = new ActiveOffersPerVendor(vendorId);

				//last for only 30 seconds. There's no possibility to actively remove the cache item
				DataCache.Insert(cacheKey, offers, DateTime.Now.AddSeconds(30));
			}
			return offers;
		}

		internal ActiveOffersToBind GetOffer(int offerId)
		{
			var retVal = this.SingleOrDefault(x => x.OfferId == (uint)offerId);
			if (retVal == null)
				throw new Exception("ActiveOffers not one rows with offerId " + offerId.ToString());

			return retVal;
		}

		public static void RemoveFromCache(uint vendorId)
		{
			string cacheKey = cacheName + vendorId.ToString();

			DataCache.Cache.Remove(cacheKey);
		}
	}
}